
/*

工厂方法类

public class NYPizzaStore extends PizzaStore {
    @Override
    Pizza CreatePizza(String type) {
        if(type.equals("cheese")) {
            return new NYStyleCheesePizza();
        }else if (type.equals("veggie")){
            return new NYStyleVeggiePizza();
        }else {
            return null;
        }
    }
}
 */


public class NYPizzaStore extends PizzaStore {
    protected Pizza createPizza(string item){
        Pizza pizza = null;
        PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();

        if(item.equals("cheese")){
            pizza = new CheesePizza(ingredientFactory);
            pizza.setName("New York Style Cheese Pizza");
        }else if (item.equals("Veggie")){
            pizza = new VeggePizza(ingredientFactory);
            pizza.setName("New York Style Veggie Pizza");
        }else if(item.equals("clam")){
            pizza = new ClamPizza(ingredientFactory);
            pizza.setName("New York Style Clam Pizza");
        }else if(item.equals("pepperoni")){
            pizza = new PepperoniPizza(ingredientFactory);
            pizza.setName("New York Style Pepperoni Pizza");
        }
        return pizza;
    }
}


/*
条件选择： 就是把要创建的产品列表，如各种pizza 放在一个if,else结构里封装成函数，传参进行选择。优点简点，缺点不符合开闭原则，耦合度高
简单工厂： 就是把创建产品列表封装成一个对象，相对来说修改只需要修改对象本身，而且对象共享使用，符合开闭原则，但是不具备扩展性。
相对来说修改只需要修改对象本身，而且对象共享使用，符合开闭原则，但是不具备扩展性。
比如你有a,b,c三款pizza,全国有几百家分店，不同地区分店pizza类别虽一样，但是调料和做法有所差异，这样你就得为不同地区建立不同的工厂以提供不同口味
的pizza，这时如果只有一个工厂就不符合了。于是有了第二种 工厂方法。
工厂方法:  就是把创建产品做成一个抽象方法，每家店可以自定义这个抽象方法。通过在基类定义createPizza为抽象方法，来实现多态，但是于此同时，你需要
创建不同pizza类，于是就有了抽象方法耦合多个pizza类。这就违反了一个原则依赖倒置原则：更高层的组件依赖具体的类，而不是依赖抽象。

如何解决？
多一层抽象，还记得第一章的设置原则吗，动静分离，把不变的分成一个组件(类)，把变的分成另一个(接口)，然后两者组合。

原先工厂方法的是做法是：pizza是基类，继承了 area_type_pizza,所以是n * n个 pizza.

每个pizzaStore的createPizza抽象方法耦合了n个pizza实体类


现状问题：创建多个n * n pizza类，createPizza耦合多个实体类而不是抽象。

抽象工厂模式：
主要做了以下的优化
1.把pizza的生产改成根据area(提供原料）抽像成interface，解决原先抽象方法createPizza的面向具体类编程，转而改成面向PizzaIngredientFactory抽象编程。
2. pizza类的生成材料不在是每个类里单独垂直创建，而是委托工厂创建（每个店都有独立一个工厂，提供了pizza的材料）
3. 原来要创建的n(area)* n(type) 个pizza，现在变成只需要创建n个type pizza，但同时pizza的材料不再是由类写死，而是去指定区域的factory里取。


 */